package com.illtamer.infinite.collapsar.dispatcher.builder;

import lombok.SneakyThrows;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Arrays;
import java.util.Objects;

/**
 * A builder for {@link Message}
 * */
public class MessageBuilder {

    protected Message message;

    /**
     * Set `Sender`(smtp), `From`, `ReplyTo` uniformly.
     * */
    public MessageBuilder source(String address) {
        return source(null, address);
    }

    @SneakyThrows({AddressException.class, MessagingException.class})
    public MessageBuilder source(String nick, String address) {
        InternetAddress sender = new InternetAddress(nick != null ? nick + " " + address : address);
        message.setFrom(sender);
        message.setReplyTo(new InternetAddress[] {sender});
        if (message instanceof MimeMessage) {
            ((MimeMessage) message).setSender(sender);
        }
        return this;
    }

    /**
     * Set the email receiver(s).
     * */
    @SneakyThrows({AddressException.class, MessagingException.class})
    public MessageBuilder to(String... address) {
        if (address.length == 1) {
            message.setRecipient(Message.RecipientType.TO, new InternetAddress(address[0]));
        } else if (address.length > 1) {
            message.setRecipients(Message.RecipientType.TO, Arrays.stream(address)
                    .map(add -> {
                        try {
                            return new InternetAddress(add);
                        } catch (AddressException e) {
                            e.printStackTrace();
                        }
                        return null;
                    })
                    .filter(Objects::nonNull)
                    .toArray(InternetAddress[]::new)
            );
        }
        return this;
    }

    @SneakyThrows
    public MessageBuilder consume(ToleratedConsumer<Message> consumer) {
        consumer.accept(message);
        return this;
    }

    public Message done() {
        return message;
    }

    /**
     * Return mime {@link MessageBuilder}
     * */
    public static SMTPMessageBuilder mime() {
        return new SMTPMessageBuilder(new MessageBuilder());
    }

}
